import { Context } from 'koa';
import { AppContext } from '@/types';
import { validate, commonSchemas } from '@/utils/validator';
import { success, paginated } from '@/utils/response';
import logger from '@/utils/logger';
import Joi from 'joi';
import Permission from '@/models/Permission.model';

interface CreatePermissionData {
  resource: string;
  action: string;
  description?: string;
}

interface ListPermissionsFilter {
  page?: number;
  pageSize?: number;
  resource?: string;
}

interface UpdatePermissionData {
  description?: string;
}

/**
 * 权限管理控制器
 */
class PermissionController {
  /**
   * 创建权限
   */
  async create(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { user } = appCtx.state;

    const schema = Joi.object({
      resource: Joi.string().required().max(100).messages({
        'string.empty': '资源名称不能为空',
        'any.required': '资源名称是必填项',
      }),
      action: Joi.string().required().valid('create', 'read', 'update', 'delete', 'manage').messages({
        'string.empty': '操作不能为空',
        'any.required': '操作是必填项',
        'any.only': '操作必须是: create, read, update, delete, manage',
      }),
      description: Joi.string().optional().allow(''),
    });

    const data = await validate<CreatePermissionData>(ctx.request.body as any, schema);

    try {
      // 检查权限是否已存在
      const existing = await Permission.findOne({
        where: {
          resource: data.resource,
          action: data.action,
        },
      });

      if (existing) {
        ctx.throw(400, '该权限已存在');
      }

      const permission = await Permission.create(data as any);

      logger.info(`权限创建成功: ${permission.resource}:${permission.action} by ${user!.email}`);
      success(ctx, permission, '权限创建成功');
    } catch (error) {
      logger.error('权限创建失败:', error);
      ctx.throw(500, '权限创建失败');
    }
  }

  /**
   * 获取权限列表
   */
  async list(ctx: Context) {
    const schema = Joi.object({
      page: commonSchemas.page,
      pageSize: Joi.number().integer().min(1).max(10000).optional().default(100), // 权限数量通常不多，允许大量获取
      resource: Joi.string().optional().allow(''),
    });

    const filter = await validate<ListPermissionsFilter>(ctx.query as any, schema);
    const page = filter.page || 1;
    const pageSize = filter.pageSize || 100; // 权限数量通常不多，默认返回更多

    try {
      const where: any = {};

      if (filter.resource) {
        where.resource = filter.resource;
      }

      const { rows: permissions, count: total } = await Permission.findAndCountAll({
        where,
        limit: pageSize,
        offset: (page - 1) * pageSize,
        order: [['resource', 'ASC'], ['action', 'ASC']],
      });

      paginated(ctx, permissions, total, page, pageSize);
    } catch (error) {
      logger.error('获取权限列表失败:', error);
      ctx.throw(500, '获取权限列表失败');
    }
  }

  /**
   * 获取所有资源列表
   */
  async resources(ctx: Context) {
    try {
      const permissions = await Permission.findAll({
        attributes: ['resource'],
        group: ['resource'],
        order: [['resource', 'ASC']],
      });

      const resources = permissions.map((p: any) => p.resource);
      success(ctx, resources);
    } catch (error) {
      logger.error('获取资源列表失败:', error);
      ctx.throw(500, '获取资源列表失败');
    }
  }

  /**
   * 获取权限详情
   */
  async detail(ctx: Context) {
    const { id } = ctx.params;

    try {
      const permission = await Permission.findByPk(id);

      if (!permission) {
        ctx.throw(404, '权限不存在');
      }

      success(ctx, permission);
    } catch (error) {
      logger.error('获取权限详情失败:', error);
      ctx.throw(500, '获取权限详情失败');
    }
  }

  /**
   * 更新权限
   */
  async update(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { user } = appCtx.state;
    const { id } = ctx.params;

    const schema = Joi.object({
      description: Joi.string().optional().allow(''),
    });

    const data = await validate<UpdatePermissionData>(ctx.request.body as any, schema);

    try {
      const permission = await Permission.findByPk(id);

      if (!permission) {
        ctx.throw(404, '权限不存在');
      }

      await permission.update(data as any);

      logger.info(`权限更新成功: ${permission.resource}:${permission.action} by ${user!.email}`);
      success(ctx, permission, '权限更新成功');
    } catch (error) {
      logger.error('权限更新失败:', error);
      ctx.throw(500, '权限更新失败');
    }
  }

  /**
   * 删除权限
   */
  async delete(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { user } = appCtx.state;
    const { id } = ctx.params;

    try {
      const permission = await Permission.findByPk(id);

      if (!permission) {
        ctx.throw(404, '权限不存在');
      }

      // 检查是否有角色使用此权限
      const RolePermission = (await import('@/models/RolePermission.model')).default;
      const count = await RolePermission.count({
        where: { permissionId: id },
      });

      if (count > 0) {
        ctx.throw(400, `该权限被 ${count} 个角色使用，无法删除`);
      }

      await permission.destroy();

      logger.info(`权限删除成功: ${permission.resource}:${permission.action} by ${user!.email}`);
      success(ctx, null, '权限删除成功');
    } catch (error) {
      logger.error('权限删除失败:', error);
      ctx.throw(500, '权限删除失败');
    }
  }
}

export default new PermissionController();

